package com.knowledgegraph.neo4j.service.impl;

import com.knowledgegraph.neo4j.entity.GraphEntity;
import com.knowledgegraph.neo4j.entity.GraphRelationship;
import com.knowledgegraph.neo4j.repository.GraphEntityRepository;
import com.knowledgegraph.neo4j.repository.GraphRelationshipRepository;
import com.knowledgegraph.neo4j.service.Neo4jRelationshipService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Neo4j 关系服务实现类
 */
@Slf4j
@Service
@Transactional
public class Neo4jRelationshipServiceImpl implements Neo4jRelationshipService {
    
    @Autowired
    private GraphRelationshipRepository relationshipRepository;
    
    @Autowired
    private GraphEntityRepository entityRepository;
    
    @Override
    public GraphRelationship createRelationship(Long startNodeId, Long endNodeId, String type, String description, Map<String, Object> properties, Long graphId) {
        try {
            // 查询起始节点和结束节点
            Optional<GraphEntity> startNodeOpt = entityRepository.findById(startNodeId);
            Optional<GraphEntity> endNodeOpt = entityRepository.findById(endNodeId);
            
            if (!startNodeOpt.isPresent()) {
                throw new RuntimeException("起始节点不存在: " + startNodeId);
            }
            if (!endNodeOpt.isPresent()) {
                throw new RuntimeException("结束节点不存在: " + endNodeId);
            }
            
            GraphEntity startNode = startNodeOpt.get();
            GraphEntity endNode = endNodeOpt.get();
            
            // 创建关系
            GraphRelationship relationship = new GraphRelationship(startNode, endNode, type);
            relationship.setDescription(description);
            relationship.setProperties(properties);
            relationship.setGraphId(graphId);
            relationship.setCreateTime(LocalDateTime.now());
            relationship.setUpdateTime(LocalDateTime.now());
            
            GraphRelationship saved = relationshipRepository.save(relationship);
            log.info("创建关系成功: {} -> {} ({})", startNode.getName(), endNode.getName(), type);
            return saved;
            
        } catch (Exception e) {
            log.error("创建关系失败", e);
            throw new RuntimeException("创建关系失败: " + e.getMessage());
        }
    }
    
    @Override
    public GraphRelationship findById(Long id) {
        Optional<GraphRelationship> relationship = relationshipRepository.findById(id);
        return relationship.orElse(null);
    }
    
    @Override
    public List<GraphRelationship> findByGraphId(Long graphId) {
        return relationshipRepository.findByGraphId(graphId);
    }
    
    @Override
    public List<GraphRelationship> findByType(String type) {
        return relationshipRepository.findByType(type);
    }
    
    @Override
    public List<GraphRelationship> findBetweenNodes(Long startNodeId, Long endNodeId) {
        return relationshipRepository.findBetweenNodes(startNodeId, endNodeId);
    }
    
    @Override
    public GraphRelationship updateRelationship(GraphRelationship relationship) {
        try {
            relationship.setUpdateTime(LocalDateTime.now());
            GraphRelationship updated = relationshipRepository.save(relationship);
            log.info("更新关系成功: {}", relationship.getId());
            return updated;
        } catch (Exception e) {
            log.error("更新关系失败", e);
            throw new RuntimeException("更新关系失败: " + e.getMessage());
        }
    }
    
    @Override
    public void deleteRelationship(Long id) {
        try {
            relationshipRepository.deleteById(id);
            log.info("删除关系成功: {}", id);
        } catch (Exception e) {
            log.error("删除关系失败", e);
            throw new RuntimeException("删除关系失败: " + e.getMessage());
        }
    }
    
    @Override
    public void deleteByGraphId(Long graphId) {
        try {
            relationshipRepository.deleteByGraphId(graphId);
            log.info("删除图谱关系成功: {}", graphId);
        } catch (Exception e) {
            log.error("删除图谱关系失败", e);
            throw new RuntimeException("删除图谱关系失败: " + e.getMessage());
        }
    }
    
    @Override
    public Long countByGraphId(Long graphId) {
        return relationshipRepository.countByGraphId(graphId);
    }
    
    @Override
    public List<GraphRelationship> findByStrengthBetween(Double minStrength, Double maxStrength) {
        return relationshipRepository.findByStrengthBetween(minStrength, maxStrength);
    }
    
    @Override
    public List<GraphRelationship> batchCreateRelationships(List<GraphRelationship> relationships) {
        try {
            // 设置创建时间
            LocalDateTime now = LocalDateTime.now();
            relationships.forEach(rel -> {
                rel.setCreateTime(now);
                rel.setUpdateTime(now);
                if (rel.getStatus() == null) {
                    rel.setStatus("active");
                }
                if (rel.getStrength() == null) {
                    rel.setStrength(1.0);
                }
                if (rel.getConfidence() == null) {
                    rel.setConfidence(1.0);
                }
            });
            
            List<GraphRelationship> saved = relationshipRepository.saveAll(relationships);
            log.info("批量创建关系成功: {} 个", saved.size());
            return saved;
            
        } catch (Exception e) {
            log.error("批量创建关系失败", e);
            throw new RuntimeException("批量创建关系失败: " + e.getMessage());
        }
    }
}